package ciyuan.Block.TypeInterface;

import ciyuan.Item.ItemRegisterManager;
import net.minecraft.block.AbstractFurnaceBlock;
import net.minecraft.block.BlockState;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.IIntArray;
import net.minecraft.util.text.ITextComponent;

public abstract class MachineTileEntity extends TileEntity implements ITickableTileEntity, INamedContainerProvider {

    private static final String STORE_ITEM_KEY = "item";
    private static final int PROGRESS_INDEX = 0;
    private static final int MACHINE_STATUS_INDEX = 1;
    private static final int FUEL_INDEX = 2;

    protected final Inventory inventory;
    private final ContainerProgress containerProgress;
    private final ITextComponent labelText;
    private final int consumeTime;

    public MachineTileEntity(TileEntityType<?> tileEntityType, int inventorySize, ITextComponent labelText, int consumeTime) {
        super(tileEntityType);
        this.inventory = new Inventory(inventorySize);
        this.containerProgress = new ContainerProgress();
        this.labelText = labelText;
        this.consumeTime = consumeTime;
    }

    @Override
    public ITextComponent getDisplayName() {
        return labelText;
    }

    @Override
    public void load(BlockState blockState, CompoundNBT nbt) {
        if (!hasLevel()) {
            for (int i = 0; i < inventory.getContainerSize(); i++) {
                this.inventory.setItem(i, ItemStack.of(nbt.getCompound(STORE_ITEM_KEY + i)));
            }
        }
        super.load(blockState, nbt);
    }

    @Override
    public CompoundNBT save(CompoundNBT compound) {
        for (int i = 0; i < this.inventory.getContainerSize(); i++) {
            ItemStack itemStack = this.inventory.getItem(i).copy();
            compound.put(STORE_ITEM_KEY + i, itemStack.serializeNBT());
        }
        return super.save(compound);
    }


    public static class ContainerProgress implements IIntArray {

        int[] progress = new int[10];

        @Override
        public int get(int index) {
            return progress[index];
        }

        @Override
        public void set(int index, int value) {
            progress[index] = value;
        }

        @Override
        public int getCount() {
            return progress.length;
        }
    }

    public int getConsumeTime() {
        return this.consumeTime;
    }

    public int getProgress() {
        return this.containerProgress.get(PROGRESS_INDEX);
    }

    public void resetProgress() {
        if (getProgress() != 0) {
            this.containerProgress.set(PROGRESS_INDEX, 0);
            this.setChanged();
        }
    }

    public int getFuel() {
        return this.containerProgress.get(FUEL_INDEX);
    }

    public boolean consumeFuel() {
        int fuel = this.containerProgress.get(FUEL_INDEX);
        if (fuel > 0) {
            this.containerProgress.set(FUEL_INDEX, fuel - 1);
            this.addProgress();
            this.setChanged();
            return true;
        }
        this.setMachineStatus(false);
        return false;
    }

    public void addProgress() {
        this.containerProgress.set(PROGRESS_INDEX, this.getProgress() + 1);
        this.setMachineStatus(true);
        this.setChanged();
    }

    public void addFuel(int count) {
        this.containerProgress.set(FUEL_INDEX, getFuel() + count);
        this.setChanged();
    }

    public ContainerProgress getContainerProgress() {
        return this.containerProgress;
    }

    public boolean getMachineStatus() {
        return this.containerProgress.get(MACHINE_STATUS_INDEX) == 1;
    }

    public void setMachineStatus(boolean isWork) {
        if (getMachineStatus() == isWork) return;
        if (isWork) {
            this.containerProgress.set(MACHINE_STATUS_INDEX, 1);
        } else {
            this.containerProgress.set(MACHINE_STATUS_INDEX, 0);
        }
        this.setChanged();
        this.level.setBlock(this.worldPosition, this.level.getBlockState(this.worldPosition).setValue(AbstractFurnaceBlock.LIT, isWork), 3);
    }

    public Inventory getInventory() {
        return this.inventory;
    }

    protected static int getFuelAddCount(Item fuel) {
        if (fuel.equals(Items.COAL)) {
            return 1000;
        } else if (fuel.equals(ItemRegisterManager.anthracite.get())) {
            return 1600;
        } else if (fuel.equals(ItemRegisterManager.lignite.get())) {
            return 500;
        }
        return 0;
    }

}
